/* -*-c++-*- */
/* osgGIS - GIS Library for OpenSceneGraph
 * Copyright 2007-2008 Glenn Waldron and Pelican Ventures, Inc.
 * http://osggis.org
 *
 * osgGIS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#ifndef _OSGGIS_TASK_H
#define _OSGGIS_TASK_H 1

#include <osgGIS/Common>
#include <queue>
#include <list>
#include <string>

namespace osgGIS
{
    /**
     * A discrete operation that may be dispatched by a TaskManager.
     */
    class OSGGIS_EXPORT Task : public osg::Referenced
    {
    public:
        /**
         * Constructs a new task.
         *
         * @param user_data
         *      Optional user data.
         */
        Task();

        /**
         * Constructs a new task
         *
         * @param name
         *      Readable name of the task.
         * @param user_data
         *      Optional user data.
         */
        Task(const std::string& name);

        /**
         * Gets the task name.
         *
         * @return Readable name of the task
         */
        const std::string& getName() const;

        /**
         * Gets the user data structure attached to this task.
         *
         * @return user data.
         */
        osg::Referenced* getUserData() const;

        /**
         * Sets the user data structure
         *
         * @param value
         *      User data.
         */
        void setUserData( osg::Referenced* user_data );

        /**
         * Puts the task into an Exception state, meaning that something
         * unrecoverable happened during its execution.
         */
        void setException();

        /**
         * Gets whether the task was put into an exception state.
         *
         * @return True or false
         */
        bool isInExceptionState() const;
        
    public:
        /** 
         * Executes the task (possibly in another thread)
         */
        virtual void run() =0;
        
    protected:
        void setName( const std::string& );
        
    private:
        std::string name;
        osg::ref_ptr<osg::Referenced> user_data;
        bool exception_state;
    };

    typedef std::queue< osg::ref_ptr<Task> > TaskQueue;
    typedef std::list< osg::ref_ptr<Task> > TaskList;
}

#endif // _OSGGIS_TASK_H
